#include "ConfigDialog.h"
#include "ui_ConfigDialog.h"

#include <QFileDialog>
#include <QDebug>
#include <QDir>
#include <QSettings>
#include <QScrollArea>
#include <QTextCodec>
#include <QMessageBox>

#include "SerialGUI.h"

static const QString configFileName = "IgnitionPanel.ini";
//static const QString configKeyName = "uart";

ConfigDialog::ConfigDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ConfigDialog)
{
    configValid = false;

    ui->setupUi(this);

    uartinfo = new QSettings(configFileName,QSettings::IniFormat);
    uartinfo->setIniCodec(QTextCodec::codecForName("UTF-8"));

    bool cfgFileValid = uartinfo->contains("DefaultSerial/Manufacturer");
    cfgFileValid = cfgFileValid && uartinfo->contains("DefaultSerial/Description");
    cfgFileValid = cfgFileValid && uartinfo->contains("DefaultSerial/VID");
    cfgFileValid = cfgFileValid && uartinfo->contains("DefaultSerial/PID");
    if(!cfgFileValid)
    {
        QMessageBox(QMessageBox::Critical,
                    configFileName,
                    tr("File %1"
                       "not found or format error")
                    .arg(configFileName),
                    QMessageBox::Abort).exec();
        //qApp->exit(-1);
        close();
    }

    connect(this,SIGNAL(serialConfigChanged(QString,QString)),
            this,SLOT(  setSerialConfig    (QString,QString)));

    ui->cfgfile_edit->setText(configFileName);
}

ConfigDialog::~ConfigDialog()
{
    delete ui;
    delete uartinfo;
    /*
    while(uartlist.count())
    {
        delete uartlist.takeLast();
    }
    */
}

void ConfigDialog::on_buttonBox_clicked(QAbstractButton *button)
{
    switch(ui->buttonBox->standardButton(button))
    {
        case QDialogButtonBox::Close:
            break;
        case QDialogButtonBox::Save:
            writeConfig();
            break;
        default:
            ;
    }
    close();
}

void ConfigDialog::on_cfgfile_button_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        tr("Open Config File"), "", tr("Settings (*.ini)"));
    if(fileName == QString::null)
    {
        //ui->cfgfile_edit->setText("");
        return;
    }
    else
    {
        QDir dir(QDir::currentPath());
        QString displayPath = dir.relativeFilePath(fileName);
        ui->cfgfile_edit->setText(displayPath);
    }
}

bool ConfigDialog::autoSelect(const QSerialPortInfo &info)
//test if object(info) can be selected
{
    QString fmanu = uartinfo->value("DefaultSerial/Manufacturer").toString();
    QString fdesc = uartinfo->value("DefaultSerial/Description").toString();
    QString fvid  = uartinfo->value("DefaultSerial/VID").toString();
    QString fpid  = uartinfo->value("DefaultSerial/PID").toString();

    return ((fmanu == info.manufacturer())
          &&(fdesc == info.description())
          &&(fvid == info.vendorIdentifier())
          &&(fpid == info.productIdentifier())
          );
          /* && info.isBusy()); */
}

void ConfigDialog::on_port_button_released()
{
    QVBoxLayout *layout = new QVBoxLayout;
    bool hasSelected = false;

    /*
    while(uartlist.count())
    {
        delete uartlist.takeLast();
    }
*/

    foreach (const QSerialPortInfo &info,
             QSerialPortInfo::availablePorts())
    {
        QString s(QObject::tr("Port:        %1\n"
                              "Location:    %2\n"
                              "Description: %3\n"
                              "Manufacturer:%4\n"
                              "Vendor ID:   %5\n"
                              "Product ID:  %6\n"
                              "Busy:        %7\n"));

        s = s.arg(info.portName()).arg(info.systemLocation())
             .arg(info.description()).arg(info.manufacturer())
             .arg(info.vendorIdentifier()).arg(info.productIdentifier())
             .arg(info.isBusy() ? QObject::tr("Yes") : QObject::tr("No"));

        QLabel *label = new QLabel(s);
        //uartlist<<label;

        layout->addWidget(label);

        label->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse);

        if(autoSelect(info))
        {
            label->setStyleSheet("color: red;");
            if(!info.isBusy() && !hasSelected)
            {
                hasSelected = true;
                s = s.append(tr("---------->>>Auto Selected"));
                label->setText(s);
                label->setStyleSheet("border: 2px solid red;"
                                     "color: red;");
                ui->port_edit->setText(info.portName());
            }
        }
    }

    if(!hasSelected)
    {
        ui->port_edit->setText("");
        QLabel *label = new QLabel(tr("Autoselect failed,\n"
                                      "Please input port name\n"
                                      "after window closed"));
        label->setStyleSheet("border: 2px solid red;"
                             "color: red;");
        //uartlist<<label;
        layout->addWidget(label);
    }

    QWidget *insideWidget = new QWidget;
    insideWidget->setLayout(layout);

    QScrollArea *area = new QScrollArea;
    area->setWidget(insideWidget);
    //add layout to area

    ui->port_button->setText(tr("SerialPort"));
    ui->port_button->setStyleSheet("color: black;");

    area->setWindowTitle(tr("SerialPort autoselect"));
    area->setWindowModality(Qt::ApplicationModal);
    area->setGeometry(30,30,320,area->height());
    //screen dependence
    area->show();
}

void ConfigDialog::on_port_button_pressed()
{
    ui->port_button->setText(tr("Please wait"));
    ui->port_button->setStyleSheet("color: red;");
}

void ConfigDialog::on_mode_button_clicked()
{
    QString modetext = uartinfo->value("DefaultSerial/mode").toString();

    QString msgtext(tr("Set as below:\n"
                       "    baudrate,databits,parity,stopbits\n\n"
                       "Default:\n"
                       "    %1\n\n"
                       "Restore to default ?"
                       ));
    msgtext = msgtext.arg(modetext);

    if(QMessageBox::information(this,tr("Serial Mode String"),msgtext,
       QMessageBox::Ok|QMessageBox::Close) == QMessageBox::Ok)
        ui->mode_edit->setText(modetext);
}

void ConfigDialog::on_cfgfile_edit_textChanged(const QString &arg1)
{
    readConfig();
}

void ConfigDialog::on_port_edit_textChanged(const QString &arg1)
{
    port = arg1;
    emit serialConfigChanged(port,mode);
}

void ConfigDialog::on_mode_edit_textChanged(const QString &arg1)
{
    mode = arg1;
    emit serialConfigChanged(port,mode);
}

void ConfigDialog::writeConfig()
{
    QSettings set(ui->cfgfile_edit->text(),QSettings::IniFormat);
    set.setIniCodec(QTextCodec::codecForName("UTF-8"));

    set.setValue("CurrentSerial/port",port);
    set.setValue("CurrentSerial/mode",mode);

    set.sync();
}

bool ConfigDialog::readConfig()
{
    QSettings set(ui->cfgfile_edit->text(),QSettings::IniFormat);
    set.setIniCodec(QTextCodec::codecForName("UTF-8"));

    port = set.value("CurrentSerial/port").toString();
    mode = set.value("CurrentSerial/mode").toString();
    //qDebug() << port;
    //qDebug() << mode;

    if(set.status() != QSettings::NoError)
    {
        //qDebug() << "settings read err";
        port = "";
        mode = "";
        emit serialConfigChanged(port,mode);
        return false;
    }

    emit serialConfigChanged(port,mode);
    return true;
}

void ConfigDialog::setSerialConfig(QString port, QString mode)
{
    configValid = SerialGUI::testConfig(port,mode);

    //qDebug() << configValid;

    ui->port_edit->setText(port);
    ui->mode_edit->setText(mode);

    if(configValid)
    {
        ui->cfgstat->setStyleSheet("background-color: rgb(0,255,40);");
        ui->cfgstat->setText("OK");
    }
    else
    {
        ui->cfgstat->setStyleSheet("background-color: red;");
        ui->cfgstat->setText("ERROR");
    }

    //ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(configValid);
}

